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"
(let ((save (when (and (looking-at "\\s-*$")
(looking-back "\\s-+" (line-beginning-position) t))
(global-set-key [remap save-buffer] 'my-save-buffer-dtws)