Estou usando os dois. Eu acho que eles se complementam.
Como você disse, o PMD funciona no código-fonte e, portanto, encontra problemas como: violação das convenções de nomenclatura, falta de chaves, verificação de nulos perdida, lista longa de parâmetros, construtor desnecessário, falta de interrupção no switch etc. O PMD também informa sobre o Ciclomático complexidade de seu código, que considero muito útil (FindBugs não fala sobre a complexidade Cyclomatic).
FindBugs funciona em bytecode. Aqui estão alguns problemas que FindBugs encontra que PMD não encontra: método equals () falha em subtipos, método clone pode retornar nulo, comparação de referência de valores booleanos, conversão impossível, 32 bits int deslocado por uma quantidade não na faixa de 0-31, uma coleção que contém a si mesma, o método equals sempre retorna verdadeiro, um loop infinito, etc.
Normalmente, cada um deles encontra um conjunto diferente de problemas. Use ambos. Essas ferramentas me ensinaram muito sobre como escrever um bom código Java.