Here's a quick attempt at a custom function that may do what you want:
(defun backward-kill-char-or-word ()
"Delete the character or word before point."
(interactive)
(if (looking-back "\\w" 1)
(backward-kill-word 1)
(backward-delete-char 1)))
This looks back one character to decide what to do. If it sees a word constituent character it kills the word, otherwise it just deletes one character. There may be other cases you needed to handle, this is "lightly tested".
You can revise this to handle whitespace in different ways. If you want to delete spaces along with the next word (which is what backward-kill-word
does), try this:
(defun backward-kill-char-or-word ()
(interactive)
(if (looking-back (rx (char word blank)) 1)
(backward-kill-word 1)
(backward-delete-char 1)))
If you want to delete a sequence of whitespace as a unit but stop at a word, try this:
(defun backward-kill-char-or-word ()
(interactive)
(cond
((looking-back (rx (char word)) 1)
(backward-kill-word 1))
((looking-back (rx (char blank)) 1)
(delete-horizontal-space t))
(t
(backward-delete-char 1))))