Q:

Interact with slack bot without a public accessible server

For some security reasons that I can't have a public accessible server to receive data from slack.
So, this is what I'm planning to do:

Inbound message from slack: using RTM API
Outbound message to slack: using RTM API or Web API

Questions:

Any better alternatives?
Any restrictions? (AFAIK, buttons and drop downs can't work)
If Web API reach rate limit, can I use incoming webhook as a backup plan?

A:

RTM only approach
Yes, that would work. With only the RTM API you are limited to: 

receiving and responding to messages
Other RTM events. 

You can't use any interactive functionality like:

Interactive components (buttons, menus, datepickers)
Dialogs

Rate limit on message posting
Using the webhook as "backup" to circumvent the rate limit is not an option, since the rate limit of posting max 1 message per second applies to all form of message posting.
From the documentation:

In general, apps may post no more than one message per second per
  channel, whether a message is posted via chat.postMessage, an incoming
  webhook, or one of the many other ways to send messages in to Slack.

Alternatives
You did not give any details about the reasons why your app can't expose an endpoint to the public Internet. But you might want to consider using a VPN tunnel like ngrok.

