The defadvice solution is not ideal. You're changing the fundamental behaviour of a function that could be called by other functions. It's better to make your own command, this should fit all your requirements:
(defun my-save-buffer-dtws (arg)
"save buffer delete trailing white space, preserve white space before point if point is past text"
(interactive "p")
(let ((save (when (and (looking-at "\\s-*$")
(looking-back "\\s-+" (line-beginning-position) t))
(match-string 0))))
(delete-trailing-whitespace)
(save-buffer arg)
(when save
(insert save)
(set-buffer-modified-p nil))))
(global-set-key [remap save-buffer] 'my-save-buffer-dtws)