Some customers use terms from the domain language interchangably and incorrectly. This has, on several occassions, lead to an implementation of a feature in a way that was not desired by the customer. Are there any techniques that can be used to enforce the correct use of terms? Are there any techniques that can be used to prevent someone from handing "back of a cigarette packet" requirements to a developer?

I find that if I'm getting confused about what's actually desired, or if I suspect that we are not using the same words in the same way, that discussing specific examples together is the quickest and most effective way of discovering that you have different ideas. (I can't tell you how many times I've been sat in a meeting, and everybody's convinced they're in agreement - and then someone describes a specific example, and suddenly half the room is nodding yes, yes, that's it, and the other half is going "wait a minute, you want what?").

Of course, this is easiest if you're in the same room when the "back of a cigarette packet" requirements get handed over, and (to my mind) easier if you are working in an iterative fashion and clarifying small numbers of requirements at a time, but I've used this in a waterfall environment when reviewing requirements - my review comments just included examples.

As a tester, I do tend to immediately start thinking of concrete examples - both happy path and edge cases. If you're a programmer, it may be a good approach to pull a tester into the conversation with the customer too - you'll both think of different examples, and each one may reveal some misconception the customer has about what you're planning to implement, or what the system currently does. Everyone has a mental model of the system - the customer is likely to be less experienced than either a programmer or a tester at describing what their mental model is, so approaching that by discussing specific examples both gives you a set of acceptance tests, and helps to support them in explaining what they really want.

Another good approach is to ensure that you don't fall into the practice of using entirely different terms inside the tech team: in one company I worked in, this practice was endemic, and it drove me crazy - my monitor was peppered with little post its for each project with business to tech translations "business name: X, tech name: Y." It also frequently led to problems of the sort you describe as the meaning of each term would drift over time. As a tester, I always looked especially carefully for integration problems in areas I knew there were different terms for - because I knew it was likely that each development team would have come to a slightly (but critically) different interpretation.

These are things I've always tried to do informally as an individual on projects, but you should check out Gojko Adzic's work if you want to hear about how people implement this more formally as a part of the way they run projects. Check out the following blog link - I'd also recommend his two books, Bridging the Communication Gap, and Specification by Example:

Don't try to "enforce" anything. As a requirements analyst it's your job to make sense of what they're saying, not the other way around.

Definitely do take the time to explain your model to them, and if they use incorrect terminology in a meeting ("blah blah warehouse") then repeat it back to them - politely - as though they'd used the correct terminology ("blah blah inventory"). In most cases they will pick up on your language, as long as you yourself are consistent with its use.

But you absolutely must ultimately let the clients speak in their own language, otherwise you're just going to create an adversarial situation and slow the entire analysis process down.

Clarify terms as necessary during the live sessions, and send out final deliverables written in your language for review (usually with a glossary of some sort). Your objective isn't to shoehorn them into your way of thinking, it is simply to understand how they do business and implement/optimize where appropriate.

Just one other quick thing:

Are there any techniques that can be used to prevent someone from handing "back of a cigarette packet" requirements to a developer?

If you have clients sending any requirements directly to a developer then you have a problem in your team or organizational structure. I'm not sure if you meant that literally, so please forgive me if I've misunderstood, but requirements should be going through a requirements analyst or business analyst, whose exclusive mandate is to translate between the business and system domains.

If you've got a tiny handful of developers that are all really good at this themselves, then, no problem - but as you're probably beginning to notice, that doesn't scale too well.