Read the Humanities
In all but the smallest development project people work with people. In all but the most abstracted field of research people write software for people to support them in some goal of theirs. People write software with people for people. It's a people business. Unfortunately what is taught to programmers too often equips them very poorly to deal with people they work for and with. Luckily there is an entire field of study that can help.
For example, Ludwig Wittgenstein makes a very good case in the Philosophical Investigations (and elsewhere) that any language we use to speak to one another is not, cannot be, a serialization format for getting a thought or idea or picture out of one person's head and into another's. Already we should be on our guard against misunderstanding when we "gather requirements." Wittgenstein also shows that our ability to understand one another at all does not arise from shared definitions, it arises from a shared experience, from a form of life. This may be one reason why programmers who are steeped in their problem domain tend to do better than those who stand apart from it.
Lakoff and Johnson present us with a catalog of Metaphors We Live By, suggesting that language is largely metaphorical, and that these metaphors offer an insight into how we understand the world. Even seemingly concrete terms like cash flow, which we might encounter in talking about a financial system, can be seen as metaphorical: "money is a fluid." How does that metaphor influence the way we think about systems that handle money? Or we might talk about layers in a stack of protocols, with some high level and some low level. This is powerfully metaphorical: the user is "up" and the technology is "down." This exposes our thinking about the structure of the systems we build. It can also mark a lazy habit of thought that we might benefit from breaking from time to time.
Martin Heidegger studied closely the ways that people experience tools. Programmers build and use tools, we think about and create and modify and recreate tools. Tools are objects of interest to us. But for its users, as Heiddeger shows in Being and Time, a tool becomes an invisible thing understood only in use. For users tools only become objects of interest when they don't work. This difference in emphasis is worth bearing in mind whenever usability is under discussion.
Eleanor Rosch overturned the Aristotelean model of the categories by which we organize our understanding of the world. When programmers ask users about their desires for a system we tend to ask for definitions built out of predicates. This is very convenient for us. The terms in the predicates can very easily become attributes on a class or columns in a table. These sorts of categories are crisp, disjoint, and tidy. Unfortunately, as Rosch showed in "Natural Categories" and later works, that just isn't how people in general understand the world. They understand it in ways that are based on examples. Some examples, so-called prototypes, are better than others and so the resulting categories are fuzzy, they overlap, they can have rich internal structure. In so far as we insist on Aristotelean answers we can't ask users the right questions about the user's world, and will struggle to come to the common understanding we need.