I did this once with GNU Parted. As I recall, both drives have to have the same cluster size, and I think it only works with FAT/FAT32, not NTFS. There are probably some commercial products capable of this as well. In a real pinch, you could probably use dd to do it, but the new drive would be a mirror image of the old. Thus, it would have the same amount of free space as the old drive.