Taking you at your word, that you want to delete, and not kill, for the char and word cases, try this.
(Killing is like "cut" - it not only deletes the text but puts it on the
kill-ring, which means it's available for yanking ("pasting"). Just deleting does not make the deleted text available for yanking.)
But if backward killing words is OK, then you don't need
my-backward-delete-word - just use
backward-kill-word in its place.
(defun my-C-w-dwim (&optional arg)
"`delete-backward-char`, but if region is active then kill region.
With prefix arg N, delete backward to the start of the Nth word."
(my-backward-delete-word (prefix-numeric-value arg)))
(kill-region (region-beginning) (region-end)))
(t (delete-backward-char 1))))
(defun my-backward-delete-word (arg)
"Like `backward-kill-word`, but just delete."
(delete-region (point) (progn (backward-word arg) (point))))
(global-set-key (kbd "C-w") 'my-C-w-dwim)