Cook the bacon. Cook bacon in a skillet until crispy. Transfer to a paper towel-lined plate, then chop or crumble. Set aside for topping.
Sauté the onion. In a large Dutch oven or soup pot, melt butter over medium heat. Add diced onion and cook for 4 to 5 minutes until softened.
Add garlic. Stir in minced garlic and cook for 30 seconds until fragrant.
Make the roux. Sprinkle flour over the onion and garlic mixture. Stir constantly for 1 to 2 minutes to cook out the raw flour taste.
Add the broth. Slowly whisk in chicken broth or vegetable broth until smooth.
Add milk and cream. Stir in whole milk and heavy cream or half-and-half.
Add vegetables and seasoning. Stir in chopped broccoli, shredded carrots, smoked paprika, dry mustard, black pepper, salt, and optional cayenne.
Simmer the soup. Bring to a gentle simmer. Cook for 18 to 22 minutes, stirring occasionally, until the broccoli and carrots are tender.
Blend slightly, optional. For a thicker soup, use an immersion blender to blend about 1/4 of the soup while leaving plenty of broccoli pieces whole.
Add the cheese. Reduce heat to low. Stir in freshly grated sharp cheddar and Monterey Jack a handful at a time until melted and smooth.
Adjust thickness. If the soup is too thick, add a splash of broth or milk. If it is too thin, simmer gently for a few extra minutes.
Taste and adjust. Taste the soup and add more salt, pepper, or cheese if needed.
Add toppings. Ladle soup into bowls and top with crispy bacon, crushed crackers, extra cheddar, green onions, and black pepper.
Serve hot. Serve with grilled cheese, extra crackers, or crusty bread.