There are only three approaches, and only one of these is immune to piracy:
1. Generate a batch of secret keys which are stored on a server somewhere (Steam or otherwise). In order for a client to validate their game, the game has to check with the central server to find out if it is valid. This requires an Internet connection at the time (which bugs a lot of people), and causes problems if the server goes away in the future or is offline temporarily. However, with a "you can only check this many keys in this sort of time interval" rule, and sufficiently complex keys, nobody can just guess keys.
2. Generate a batch of secret keys and embed them in the game, then give those to places like Steam for registration. Anyone can just decompile the game and pull the keys directly out, plus anytime more keys are needed to be generated the game must be recompiled. Plus it uses more RAM and takes longer to check the keys in this fashion.
3. Algorithmic key checks. These are much more common than #2. Basically a key is generated by an algorithm, and the game itself is able to look at a key and know "is this a valid key" by doing the reverse of the algorithm (or something along those lines, but that's the simple explanation). You then generate a number of these keys and give them to Steam or whatever.
We take option 3. Unless you want us to start taking the route that everybody moans over of more restrictive online-checked DRM, there's not much we can really do about the pirates. Though one good solution would also be to stop letting anyone register their non-Steam keys with Steam.
It's kind of a stinky situation all around. Freedom versus security is always the sliding scale, and we lean heavily toward the freedom end compared to, say, Ubisoft.