I've implemented this in two ways.
Like umeli wrote, in the ACL remove the "delete documents" rights from people, but finesse this by allowing servers to retain deletion rights.
In a CRM database I set the Database Script QueryDocumentDelete routine to assign 'continue' the value 'False'. If the user is in the Notes Client, then give them a dialog with something like "Please raise a Support Request with a justification to delete this document". Operations could then set the form field to 'Garbage' and server automation would delete the document on schedule.
In an SaaS application a soft-delete similar to the technique umeli suggests was implemented.