Preheat oven to 350°F (175°C). Butter a 9x13-inch baking dish or a deep 10-inch skillet. If bread is soft, spread cubes on a sheet pan and toast for 8–10 minutes to dry.
Bake whole hazelnuts on a sheet pan for 8–10 minutes until fragrant. Rub in a towel to remove most skins and roughly chop.
Whisk sugar, cocoa powder, espresso powder (optional), and salt in a large bowl to break up lumps.
Whisk in eggs until smooth. Add milk, cream, vanilla, and bourbon or liqueur if using. Whisk until custard is uniform and cocoa dissolves.
Add bread cubes to a large mixing bowl. Pour half the custard over bread and toss gently. Add chopped dark chocolate and half the hazelnuts.
Let mixture sit and soak for 10–15 minutes, tossing once or twice.
Transfer half the soaked bread to the prepared dish. Dollop and swirl half the chocolate-hazelnut spread over it. Add remaining bread, swirl remaining spread on top, and sprinkle remaining hazelnuts.
Slowly pour remaining custard over bread, pressing lightly so top pieces remain slightly proud for crisp edges.
Bake uncovered for 40–50 minutes until center jiggles slightly but is not liquid. A knife near the center should come out with thick custardy streaks.
Cool for 10–15 minutes to set custard for cleaner slicing.
Dust with powdered sugar and serve warm with ice cream, whipped cream, or warm sauce.
Variations: swap breads like croissants or sourdough to create different textures and flavors.