I like simple diagrams drawn by hand for design explanations. But you have to keep it really simple, don't overload it with full architecture diagrams and every little detail. Talking your colleagues around the diagram will make it a good discussion and if they ask questions about it the time is worth so much more than a speech of your own.
When it comes to documenting the code, I'm a huge fan of Clean Code. If you are carefully naming everything you should only drop a line of comment if there really is a design decision behind the code that made you choose an uncommon way. I generally avoid lots of documentation (like javadoc) in my code.
Here's what I do:
- keep methods simple
- 1 level of detail in your methods
- good names for variables, methods, classes
I also try to avoid the hackery stuff in my code. If you need to explain a single line in your code, because you used the fanciest and shortest way to do things, you probably drive The Next Developer crazy.
And, the big thing: Provide test cases (maybe unit tests) for your code, so other developers can run them, see what happen and actually see how your code was intended to be used. I think having test cases as a way to document your code is a really nice way for other developers to get used to your code. Same rules apply to test cases than to your code: Make it clean.