Since you already know categories is an array, especially the empty array ( no category), the action has to be separated.
1.To answer your first question:
You need 'Send an HTTP request' action within Outlook 365 connector.
After that, In any condition express use empty to apply it, then compare to true/false, or use not, For example , use 'Filter array' as below not(empty()).
{
"type": "Query",
"inputs": {
"from": "@body('Send_an_HTTP_request')?['value']",
"where": "@not(empty(item()?['categories']))"
},
"runAfter": {
"Send_an_HTTP_request": [
"Succeeded"
]
}
}
2. To answer your 2nd question:
empty function will take care null; empty(null array) is equal to true, you can use if condition here.
3. To answer your 3rd question: (for your reference)
When you handle array, for example attachments, categories, etc.
- Always remind you that might be empty value exist.
- empty(), length(), coalesce() will you top 3 function in your list.
- When you have loop, note that if you have any empty/null value invoked.
- Not, true and false is top 3 when you compare empty/null value in power automate.
- Before create robust flow, test each scenario.
- Parameterization as much as you can.
- Always consider API consumption.
Share my screenshot which filter non-categorized email, and assign categories to those.

Enjoy Power Platform and have a great day 🚀 | My LinkedIn
If the answer helps, please consider 👍, Thanks.