It's a combination of taking user requirements and reading code.

* Users rarely know what they need, and when they do they're likely to tell you something that they think will get them what they think they want.

* When reading stupid code, I try to figure out, "What non-stupid reason would lead someone to do this?"

Everyone has reasons for what they do, reasons that make sense to them.