I'm currently doing the same thing, making up a tile based world using one texture page made up of lot's of subtextures.
Firstly the problem is caused by two things - the texture filtering taking into account the surrounding pixels and blends them together and also mip-mapping which, with each mip-map, a filter is appied which also blends together the surrounding pixels.
You can virtually stop the bleeding by adding a 2 pixel border around each sub-texture in the texture page and alter the UV's to fit by bringing them in by two pixels -
UVpinch# = 2.0*(1.0/TexturePageSize#)
The 2 pixel border must be as though the texture is repeated, which can be done in the great Image packer app, using the repeat border type :-
http://www.blitzbasic.com/toolbox/toolbox.php?tool=54 (using a little function I did - shameless plug ;) ).
It is also handy for putting together the texture pages in the first place.
So, for example - I use 124x124 source textures for my tile based world. I use image packer to add the 2 pixel borders and build up a 512x512 texture page that contains 16 sub-textures, then use this texture page directly in the game.
You can't stop the bleeding completely because of the mip-maps, but adding a 2 pixel border seems to fix it most of the time. You can always experiment with different border sizes the image packer allows you to do that, see what works for your game...
hope that helps,