Oracle Optimizer refuses to use my index
The optimizer does not use your index, not because it does not want to, but becasue it can not. For a query like that the index does not cover all possible outcomes.

When :a, :b, :c are all NULL, and you are searching for rows where column1, column2, column3 are all NULL, those rows are not indexed by a (column1, column2, column3) b-tree index, so it can not be used for retreiving the matching rows.

Adding NOT NULL constraints may help, but if you have NULL values, that is of course not possible (and I am assuming you have NULL values, otherwise why would you construct a query like this).

You could also try creating an index that includes a constant value, so even those rows will be indexed, where the indexed columns are NULL. So instead of an (column1, column2, column3) index, you could try creating a (column1, column2, column3, 'A') index.

The best solution in my opinion is however to have different queries generated whenever a bind variable was not assigned a value. Queries like the above are results of trying to handle multiple cases with a single query. This may seem to be elegant and compact, and yes, I know, generating different queries based on the presence of parameters can be cumbersome, but I have seen this kind of laziness causing severe performance issues countless times.

Yes, Oracle has some tricks such as NVL optimization, OR-expansion, for handling such predicates. Those work perfectly in Powerpoint and training materials, with simple examples, but in reality, with complex queries they can not be always used.