Last week I removed "final" from most class and method declarations in product classes. I left it on several User API classes that represent enumerated types.
The reason for removing "final" is to better facilitate mocking in UnitTests. The enumerated types in the User API are very simple and we're unlikely to mock them for any reason. If you do need to mock one, then it's probably ok to just remove "final" from the class and its methods. As a general rule of thumb, I would encourage only using "final" on member variables. You might also find it useful to use "final" on local variables or method parameters, especially to help with refactoring large methods. Outside of product code, we still have "final" on a number of tests that have complicated class hierarchies with methods such as setUp() on a super class that should not be overridden. I left those alone, but in the future I would suggest 1) avoid class hierarchies for dunit or junit tests, 2) give the setUp and tearDown methods on any super test classes a very unique name such as setUpMyTestBase() to eliminate the likelihood that someone might unintentionally override a method.