Let me just preface this question with a few things:
It works because the buttonWorking_Click async code (DelayAsync as well as the async lambda passed to Task.Run) does not have a current SynchronizationContext, whereas the buttonDeadlock_Click async code (DelayAsync) does. You can observe the difference by running in the debugger and watching SynchronizationContext.Current.
I explain the details behind the deadlock scenario in my blog post Don't Block on Async Code.