1. Make classes do one thing that is basically summarized in the class name. (This also takes care of 'separation of concerns')
2. Be careful to not over-abstract. That results in many tiny classes, aka ravioli code. Nobody, not even you, will remember what all those little bastards do. 3. If a class is bigger than a page (or two) of code, it's probably too long.
4. Design patterns are for inspiration, not the law. Solve problems, don't prove how smart you are.
5. Make your classes as simple as possible. You will thank yourself later.
6. If you have to write a comment that explains how some confusing thing works; that code block is a good refactoring candidate.
7. Refactor, refactor, refactor. Refactoring is rewriting code for clarity. The more you do this, the more your code will become clear to the reader. I find refactoring often reduces my LOC drastically.
8. If you just learned a technique/pattern and that technique/pattern is suddenly popping up everywhere in your code; make sure you aren't just using it because it's fun. Say you just learned what a singleton pattern is, now your code is littered with singletons. That's a good sign that you are forcing yourself to use your new found toy and reconsider.
9. Long method names. Don't be afraid to have long method names. Yes, it looks ugly, yes it takes time but you will thank yourself later and often a long method name will compensate for the lack of documentation on that method.
10. Your program should basically be a bag of loosely related, self-contained components. Think of them like parts of an engine, they each do one thing very well and they each have an interface to the rest of the engine. Also, they can individually be swapped out for another component (as long as they bolt up to the engine appropriately).
Understanding OOP is definitely a paradigm shift in thinking and it is also loaded with many a foot gun (especially when you are new).